package org.asiainfo.common.mybatis.utils;

import cn.hutool.core.util.ObjectUtil;
import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryMethods;
import com.mybatisflex.core.query.QueryWrapper;
import org.asiainfo.common.satoken.utils.LoginHelper;
import org.asiainfo.system.api.model.LoginUser;
import org.asiainfo.system.api.model.RoleDTO;

import java.util.List;

import static com.mybatisflex.core.query.QueryMethods.bracket;
import static com.mybatisflex.core.query.QueryMethods.select;

/**
 * 数据权限工具类
 *
 * @author dotor-ww
 */
public class DataScopeUtils {

    /**
     * 全部数据权限
     */
    public static final String DATA_SCOPE_ALL = "1";

    /**
     * 自定数据权限
     */
    public static final String DATA_SCOPE_CUSTOM = "2";

    /**
     * 部门数据权限
     */
    public static final String DATA_SCOPE_DEPT = "3";

    /**
     * 部门及以下数据权限
     */
    public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";

    /**
     * 仅本人数据权限
     */
    public static final String DATA_SCOPE_SELF = "5";

    /**
     * 添加数据权限条件
     *
     * @param queryWrapper 查询条件
     */
    public static QueryWrapper addCondition(QueryWrapper queryWrapper) {
        QueryCondition queryCondition = QueryCondition.createEmpty();

        //获取用户信息
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (ObjectUtil.isNull(loginUser) || LoginHelper.isSuperAdmin()) {
            //如果数据权限包含全部数据，直接返回原始的 queryWrapper
            return queryWrapper;
        }

        //是否是管理员
        List<RoleDTO> roles = loginUser.getRoles();

        //生成数据权限
        List<String> dataScopeList = roles.stream()
            .map(RoleDTO::getDataScope)
            .filter(dataScope -> !DATA_SCOPE_CUSTOM.equals(dataScope))
            .distinct()
            .toList();

        //1.查询全部数据
        if (dataScopeList.contains(DATA_SCOPE_ALL)) {
            return queryWrapper;
        }

        //2.查询自定义数据
        for (String dataScope : dataScopeList) {
            if (DATA_SCOPE_CUSTOM.equals(dataScope)) {
                //SQL: or sys_dept.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE sys_role_dept.role_id = #{roleId} )
                queryCondition
                    .or(new QueryColumn("sys_dept", "dept_id").in(
                        select(new QueryColumn("sys_role_dept", "dept_id"))
                            .from("sys_role_dept")
                            .where(new QueryColumn("sys_role_dept", "role_id").eq(loginUser.getRoleId()))
                    ));
            }
        }

        //3.查询本部门数据
        if (dataScopeList.contains(DATA_SCOPE_DEPT)) {
            //SQL: or sys_dept.dept_id = #{roleId}
            queryCondition.or(new QueryColumn("sys_dept", "dept_id").eq(loginUser.getDeptId()));
        }

        //4.查询本部门及以下数据
        if (dataScopeList.contains(DATA_SCOPE_DEPT_AND_CHILD)) {
            //SQL: or sys_dept.dept_id IN ( SELECT dept_id FROM sys_dept WHERE sys_dept.dept_id = #{deptId} or find_in_set(#{deptId} , sys_dept.ancestors)
            queryCondition.or(new QueryColumn("sys_dept", "dept_id")
                .in(select(new QueryColumn("sys_dept", "dept_id"))
                    .from("sys_dept")
                    .where(new QueryColumn("sys_dept", "dept_id").eq(loginUser.getDeptId()))
                    .or(QueryMethods.findInSet(QueryMethods.number(loginUser.getDeptId()), new QueryColumn("sys_dept", "ancestors")).gt(0))));
        }

        //5.查询本人数据
        if (dataScopeList.contains(DATA_SCOPE_SELF)) {
            //OR sys_user.user_id = #{userId}
            queryCondition.or(new QueryColumn("sys_user", "user_id").eq(loginUser.getUserId()));
        }

        //所有新增的查询条件外边用圆括号包括起来
        queryWrapper.and(bracket(queryCondition));

        return queryWrapper;
    }
}
